#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/wait.h>

#define NUM 10
typedef void (*FUN)();
FUN fun_arr[NUM];

void fun1()
{
    printf("此函数将检查其他任务的完成情况\n");
}

void fun2()
{
    printf("此函数将绘制图形界面\n");
}

void fun3()
{
    printf("此函数将检查网络连接情况\n");
}

int AddFun(FUN f)
{
    int i = 0;
    for(; i < NUM; i++)
    {
        if(fun_arr[i] == NULL) break;
    }

    if(i == NUM)
        return -1;
    fun_arr[i] = f;
    return 0;
}

int DelFun()
{
    return 0;
}

void Init()
{
    for(int i = 0; i < NUM; i++)
    {
        fun_arr[i] = NULL;
    }
    AddFun(fun1);
    AddFun(fun2);
    AddFun(fun3);
}

void ExecuteFun()
{
    for(int i = 0; i < NUM; i++)
    {
        if(fun_arr[i])
            fun_arr[i]();
    }
}

int main()
{
    pid_t id = fork();
    if(id > 0)
    {
      //  int cnt = 10;
      //  //父进程
      //  for(int i = 0; i < cnt; i++)
      //  {
      //      printf("我是父进程，pid:%d,ppid:%d\n",getpid(),getppid());
      //      sleep(1);
      //  }
        int status = 0;
        pid_t ret;
        Init();
        while(1)
        {
            //ret = waitpid(id,&status,0);
            ret = waitpid(id,&status,WNOHANG);
            if(ret > 0)
            {
                //waitpid调用成功
                //之后根据status的值，调用宏函数，得到子进程的运行是否成功的信息
                if(WIFEXITED(status))
                {
                    printf("进程是正常跑完的，退出码为:%d\n",WEXITSTATUS(status));
                }
                else
                {
                    printf("进程出现了异常\n");
                }
                break;
            }
            else if(ret < 0)
            {
                //waitpid调用失败，例：没有进程要回收，或者被信号终止了回收过程
                printf("进程资源回收失败\n");
                break;
            }
            else
            {
                //waitpid设置了第三个参数，子进程进行了单次非阻塞等待
                //之后可以放在while中进行循环等待
                ExecuteFun();
                sleep(1);
            }
        }

    }
    else if(id == 0)
    {
        //子进程
        int cnt = 5;
        for(int i = 0; i < cnt; i++)
        {
            printf("我是子进程，pid:%d,ppid:%d\n",getpid(),getppid());
            sleep(1);
        }
        exit(0);
    }
    else
    {
        //创建进程失败，例如内存空间不足
        perror("fork failed");
        return 1;
    }
    return 0;
}
